package midi.theory;

import midi.basic.Configure;
import midi.basic.Mode;
import midi.basic.ToneEnum;
import midi.basic.Voice;

/**
 * 音的唱名表示法
 * 当唱名的唱名名称，调式和8度位置确定了，它的id也确定了
 * 例子：ToneEnum(ToneEnum.d,Mode.C,0)表示C调的唱名do，8度偏移量为0
 */
public class Tone extends Voice {
    //唱名
    ToneEnum toneEnum;
    //调式
    Mode mode;
    //位置
    int position;


    //获取音高编号0-127

    @Override
    public int id() {
        return id;
    }

    //根据唱名枚举、调式和位置构建一个唱名
    public Tone(ToneEnum toneEnum, Mode mode, int position) {
        this.toneEnum = toneEnum;
        this.mode = mode;
        this.position = position;
        this.id = Configure.MainC + mode.getOffset() + toneEnum.offset() + 12 * position;
    }

    //根据调式和音编号构建一个唱名
    public Tone(int id, Mode mode) {
        this.mode = mode;
        this.toneEnum = ToneEnum.fromId(id, mode);
        if (id - mode.getOffset() >= 60) {
            this.position = (id - mode.getOffset() - 60) / 12;
        } else {
            this.position = -(60 - id - mode.getOffset() - 1) / 12 - 1;
        }
        this.id = id;
    }

    public String toString() {
        return String.format("[%d,%s,%s,%d]", this.id, toneEnum.getToneString(), mode.getModeString(), position);
    }
}
